package com.hxzy.shop.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hxzy.shop.cachedao.AuthCacheService;
import com.hxzy.shop.common.dto.auth.AuthMapStructConvert;
import com.hxzy.shop.common.dto.auth.req.AccountListReq;
import com.hxzy.shop.common.dto.auth.req.AddAccountReq;
import com.hxzy.shop.common.dto.auth.req.EditAccountReq;
import com.hxzy.shop.common.dto.auth.resp.AccountDetailResp;
import com.hxzy.shop.common.dto.auth.resp.AccountListResp;
import com.hxzy.shop.constant.AuthConstant;
import com.hxzy.shop.constant.RedisConstant;
import com.hxzy.shop.dto.auth.resp.LoadUserResp;
import com.hxzy.shop.entity.AdminAccount;
import com.hxzy.shop.entity.AdminAccountInnerRole;
import com.hxzy.shop.mapper.AccountMapper;
import com.hxzy.shop.mapper.AdminAccountInnerRoleMapper;
import com.hxzy.shop.properties.RSAProperties;
import com.hxzy.shop.service.AdminAccountService;
import com.hxzy.shop.utils.RsaUtils;
import com.hxzy.shop.vo.ApiException;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;

/**
 * 功能描述 账号
 *
 * @author tonneyyy
 */
@Service
public class AdminAccountServiceImpl extends ServiceImpl<AccountMapper, AdminAccount> implements AdminAccountService {

    @Resource
    private AccountMapper  accountMapper;

    @Autowired
    private AdminAccountInnerRoleMapper adminAccountInnerRoleMapper;

    @Autowired
    private RSAProperties rsaProperties;

    @Autowired
    private AuthCacheService authCacheService;


    /**
     * 分页查询
     * @param req
     * @return
     */
    @Override
    public PageInfo<AccountListResp> search(AccountListReq req) {
        return PageHelper.startPage(req.getPageNum(),req.getPageSize()).doSelectPageInfo(()->{
            accountMapper.search(req);
        });
    }

    /**
     * 新增账号
     * @param req
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int addAccount(AddAccountReq req) {
        AdminAccount db = this.accountMapper.findAccountByAccount(req.getAccount());
        if(Objects.nonNull(db)){
            throw new ApiException(500, "账号已存在");
        }

        AdminAccount entity = AuthMapStructConvert.INSTANCE.toEntity(req);
        entity.setState(Boolean.TRUE);
        entity.setRoot(Boolean.FALSE);
        entity.setCreateTime(new Date());
        entity.setPassword(BCrypt.hashpw(req.getPassword()));
        entity.setPwd(RsaUtils.priEnc(req.getPassword(),rsaProperties.getPrivateKeyStr(),rsaProperties.getPublicKeyStr()));

        int count = this.accountMapper.insert(entity);

        //再添加角色信息
        if(count>0){
            AdminAccountInnerRole accountInnerRole=new AdminAccountInnerRole();
            accountInnerRole.setAccountId(entity.getId());
            accountInnerRole.setRoleId(req.getRoleId());
            count+=this.adminAccountInnerRoleMapper.insert(accountInnerRole);
        }
        return count;
    }

    /**
     * 帐号详情
     * @param accountId
     * @return
     */
    @Override
    public AccountDetailResp accountDetail(Long accountId) {
        LoadUserResp loadUserResp = this.accountMapper.findAccountAndRoleByAccountId(accountId);
        if (ObjectUtil.isEmpty(loadUserResp)) {
            throw new ApiException(500, "账号不存在");
        }
        AccountDetailResp resp = new AccountDetailResp();
        resp.setAccountId(loadUserResp.getId());
        resp.setName(loadUserResp.getName());
        resp.setPhone(loadUserResp.getPhone());
        resp.setAccount(loadUserResp.getAccount());
        resp.setPwd(RsaUtils.pubDec(loadUserResp.getPwd(), rsaProperties.getPrivateKeyStr(), rsaProperties.getPublicKeyStr()));
        resp.setRoleId(loadUserResp.getRoleId());
        resp.setRoleName(loadUserResp.getRoleName());
        resp.setSub(loadUserResp.getSub());
        return resp;
    }

    /**
     * 修改账号
     * @param req
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int editAccount(EditAccountReq req) {
        Long accountId = req.getAccountId();
        AdminAccount account = this.accountMapper.selectById(accountId);
        if (ObjectUtil.isEmpty(account)) {
            throw new ApiException(500, "账号不存在");
        }
        account.setName(req.getName());
        account.setPhone(req.getPhone());
        account.setSub(req.getSub());
        String password = req.getPassword();
        if (!BCrypt.checkpw(password, account.getPassword())) {
            account.setPassword(BCrypt.hashpw(password));
            account.setPwd(RsaUtils.priEnc(password, rsaProperties.getPrivateKeyStr(), rsaProperties.getPublicKeyStr()));
            CompletableFuture.runAsync(() -> {
                //清空之前登录状态的用户
                String key = RedisConstant.AUTHORIZATION + AuthConstant.ADMIN_CLIENT_ID + ":" + account.getAccount() + String.valueOf(account.getMerchantId());
                authCacheService.emptyToken(key);
            });
        }
        account.setAvatar(req.getAvatar());
        account.setUpdateTime(new Date());
        int count= accountMapper.updateById(account);
        AdminAccountInnerRole accountInnerRole = this.adminAccountInnerRoleMapper.findAccountInnerRoleByAccountId(accountId);
        if (!ObjectUtil.isEmpty(accountInnerRole)) {
            this.adminAccountInnerRoleMapper.deleteById(accountInnerRole.getId());
        }
        accountInnerRole = new AdminAccountInnerRole();
        accountInnerRole.setAccountId(accountId);
        accountInnerRole.setRoleId(req.getRoleId());
        count= this.adminAccountInnerRoleMapper.insert(accountInnerRole);
        return count;
    }
}
